<?php
namespace frontend\controllers;

use common\models\c2\entity\CardHold;
use common\models\c2\entity\FeUser;
use common\models\c2\entity\Lesson;
use common\models\c2\entity\LessonApply;
use common\models\c2\entity\LessonDaily;
use common\models\c2\statics\LessonDailyStatus;
use frontend\models\ResendVerificationEmailForm;
use frontend\models\VerifyEmailForm;
use kzo\base\models\statics\EntityModelStatus;
use kzo\base\models\statics\OperationResult;
use kzo\base\models\statics\ResponseDatum;
use Yii;
use yii\base\InvalidArgumentException;
use yii\db\Exception;
use yii\rest\Action;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use frontend\models\ContactForm;

/**
 * Site controller
 */
class SiteController extends \yii\rest\Controller
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['logout', 'signup'],
                'rules' => [
                    [
                        'actions' => ['signup'],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    [
                        'actions' => ['logout'],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'logout' => ['post'],
                ],
            ],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }

    /**
     * Displays homepage.
     *
     * @return mixed
     */
    public function actionIndex()
    {
        $date = Yii::$app->request->post('date');
        $user_id = Yii::$app->request->post('user_id');

        $lessonDailies = LessonDaily::find()
            ->where(['lesson_at' => $date, 'status' => EntityModelStatus::STATUS_ACTIVE])
            ->all();

        if ($user_id != 0 && !is_null($user_id)) {
            foreach ($lessonDailies as &$lessonDaily) {
                $arr = $lessonDaily->toArray();
                foreach ($arr['lesson_applies'] as $lesson_apply) {
                    $lesson_apply['user_id'] == $user_id ? $lessonDaily->is_applied = 1 : $lessonDaily->is_applied = 0;
                    break;
                }
            }
        }

        return $this->asJson(ResponseDatum::getSuccessDatum([], $lessonDailies));
    }

    public function actionProve()
    {
        $mobile_number = Yii::$app->request->post('mobile_number');
        $user = FeUser::findOne([
            'mobile_number' => $mobile_number
        ]);
        if ($user) {
            return $this->asJson(ResponseDatum::getSuccessDatum(['message' => Yii::t('app.c2', 'Proved Success')], $user));
        }
        return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Mobile Number Proved Fail')]));

    }

    public function actionCancel()
    {
        $uid = Yii::$app->request->post('user_id');
        $lesson_daily_id = Yii::$app->request->post('lesson_daily_id');

        $lessonApply = LessonApply::findOne([
            'user_id' => $uid,
            'lesson_daily_id' => $lesson_daily_id,
        ]);

        if (is_null($lessonApply)) {
            // 未预约
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Not Applied')]));
        }

        $transaction = Yii::$app->db->beginTransaction();

        $lessonDaily = LessonDaily::findOne($lessonApply->lesson_daily_id);
        $cardHold = CardHold::findOne($lessonApply->card_hold_id);

        if (!is_null($lessonDaily) && !is_null($cardHold)) {

            $lessonDate = getdate(strtotime($lessonDaily->lesson_at));
            $today = getdate(strtotime(date("Y-m-d H:i:s", time())));

            if ($lessonDate['year'] == $today['year'] && $lessonDate['yday'] == $today['yday']) {
                if (strtotime("+2 hours") > strtotime($lessonDaily->lesson_daytime)) {
                    // 2小时内不能报名
                    return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson cancel before 2hours.')]));
                }

                // if (strtotime("-2 hours") > strtotime($lessonDaily->lesson_daytime)) {
                //     // 已过报名时间
                //     return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson apply not in time.')]));
                // }
            }

            // 课程剩余人数
            $lessonDaily->updateCounters(['remain_num' => 1]);
            // 会员卡次数
            $cardHold->updateCounters(['remain_time' => 1]);
            try {
                $lessonApply->delete();
                $transaction->commit();
                return $this->asJson(ResponseDatum::getSuccessDatum(['message' => Yii::t('app.c2', 'Lesson Cancel Success')]));
            } catch (Exception $e) {

            } catch (\Throwable $e) {

            }
        }

        return $this->asJson(ResponseDatum::getSuccessDatum(['message' => Yii::t('app.c2', 'Lesson Cancel Fail')]));
    }

    public function actionApply()
    {
        $uid = Yii::$app->request->post('user_id');
        $lesson_daily_id = Yii::$app->request->post('lesson_daily_id');

        $checkApply = LessonApply::findOne([
            'user_id' => $uid,
            'lesson_daily_id' => $lesson_daily_id,
        ]);

        if ($checkApply) {
            // 已报名
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Applied')]));
        }

        $lessonDaily = LessonDaily::findOne($lesson_daily_id);

        if (is_null($lessonDaily)) {
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Apply Fail')]));
        }

        if ($lessonDaily->status == LessonDailyStatus::TYPE_CANCEL) {
            // 课程取消
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Cancel')]));
        }

        if ($lessonDaily->remain_num <= 0) {
            // 满人
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Without')]));
        }

        $lessonDate = getdate(strtotime($lessonDaily->lesson_at));
        $today = getdate(strtotime(date("Y-m-d H:i:s", time())));

        if ($lessonDate['year'] == $today['year'] && $lessonDate['yday'] == $today['yday']) {
            if (strtotime("+2 hours") > strtotime($lessonDaily->lesson_daytime)) {
                // 2小时内不能报名
                return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson apply not in time.')]));
            }

            // if (strtotime("-2 hours") > strtotime($lessonDaily->lesson_daytime)) {
            //     // 已过报名时间
            //     return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson apply not in time.')]));
            // }
        }

        // 多张会员卡找一张有效的
        $cardHold = CardHold::find()
            ->where([
                'user_id' => $uid,
                'status' => EntityModelStatus::STATUS_ACTIVE,
            ])
            ->andWhere(['>=', 'expired_at', date("Y-m-d", time())])
            ->andWhere(['>', 'remain_time', 0])->one();

        if (is_null($cardHold)) {
            // 没有会员卡或者会员卡失效
            return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Card hold expired or not exist.')]));
        }

        $transaction = Yii::$app->db->beginTransaction();

        // 课程剩余人数
        $lessonDaily->updateCounters(['remain_num' => -1]);
        // 会员卡次数
        $cardHold->updateCounters(['remain_time' => -1]);

        $lessonApply = new LessonApply();
        $lessonApply->lesson_daily_id = $lessonDaily->id;
        $lessonApply->user_id = $uid;
        $lessonApply->card_hold_id = $cardHold->id;
        if ($lessonApply->save()) {
            try {
                $transaction->commit();
                return $this->asJson(ResponseDatum::getSuccessDatum(['message' => Yii::t('app.c2', 'Lesson Apply Success')]));
            } catch (Exception $e) {

            }
        }
        return $this->asJson(ResponseDatum::getErrorDatum(['message' => Yii::t('app.c2', 'Lesson Apply Fail')]));

    }

    /**
     * Logs in a user.
     *
     * @return mixed
     */
    public function actionLogin()
    {
        if (!Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            $model->password = '';

            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Logs out the current user.
     *
     * @return mixed
     */
    public function actionLogout()
    {
        Yii::$app->user->logout();

        return $this->goHome();
    }

    /**
     * Displays contact page.
     *
     * @return mixed
     */
    public function actionContact()
    {
        $model = new ContactForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
                Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
            } else {
                Yii::$app->session->setFlash('error', 'There was an error sending your message.');
            }

            return $this->refresh();
        } else {
            return $this->render('contact', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Displays about page.
     *
     * @return mixed
     */
    public function actionAbout()
    {
        return $this->render('about');
    }

    /**
     * Signs user up.
     *
     * @return mixed
     */
    public function actionSignup()
    {
        $model = new SignupForm();
        if ($model->load(Yii::$app->request->post()) && $model->signup()) {
            Yii::$app->session->setFlash('success', 'Thank you for registration. Please check your inbox for verification email.');
            return $this->goHome();
        }

        return $this->render('signup', [
            'model' => $model,
        ]);
    }

    /**
     * Requests password reset.
     *
     * @return mixed
     */
    public function actionRequestPasswordReset()
    {
        $model = new PasswordResetRequestForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->sendEmail()) {
                Yii::$app->session->setFlash('success', 'Check your email for further instructions.');

                return $this->goHome();
            } else {
                Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.');
            }
        }

        return $this->render('requestPasswordResetToken', [
            'model' => $model,
        ]);
    }

    /**
     * Resets password.
     *
     * @param string $token
     * @return mixed
     * @throws BadRequestHttpException
     */
    public function actionResetPassword($token)
    {
        try {
            $model = new ResetPasswordForm($token);
        } catch (InvalidArgumentException $e) {
            throw new BadRequestHttpException($e->getMessage());
        }

        if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
            Yii::$app->session->setFlash('success', 'New password saved.');

            return $this->goHome();
        }

        return $this->render('resetPassword', [
            'model' => $model,
        ]);
    }

    /**
     * Verify email address
     *
     * @param string $token
     * @throws BadRequestHttpException
     * @return yii\web\Response
     */
    public function actionVerifyEmail($token)
    {
        try {
            $model = new VerifyEmailForm($token);
        } catch (InvalidArgumentException $e) {
            throw new BadRequestHttpException($e->getMessage());
        }
        if ($user = $model->verifyEmail()) {
            if (Yii::$app->user->login($user)) {
                Yii::$app->session->setFlash('success', 'Your email has been confirmed!');
                return $this->goHome();
            }
        }

        Yii::$app->session->setFlash('error', 'Sorry, we are unable to verify your account with provided token.');
        return $this->goHome();
    }

    /**
     * Resend verification email
     *
     * @return mixed
     */
    public function actionResendVerificationEmail()
    {
        $model = new ResendVerificationEmailForm();
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->sendEmail()) {
                Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
                return $this->goHome();
            }
            Yii::$app->session->setFlash('error', 'Sorry, we are unable to resend verification email for the provided email address.');
        }

        return $this->render('resendVerificationEmail', [
            'model' => $model
        ]);
    }
}
